﻿using Microsoft.AspNetCore.Mvc;
using ShenNius.Repository;
using ShenNius.Sys.API.Domain.Entity;
using ShenNius.Sys.API.Domain.Repository;
using ShenNius.Sys.API.Dtos.Common;
using ShenNius.Sys.API.Dtos.Input;
using ShenNius.Sys.API.Infrastructure;
using ShenNius.Sys.API.Infrastructure.Attributes;
using ShenNius.Sys.API.Infrastructure.Configs;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ShenNius.Sys.API.Controllers
{
    public class MenuController : ApiControllerBase
    {
        private readonly IMenuRepository _menuRepository;
        private readonly IBaseRepository<Config> _configRepository;
        private readonly IBaseRepository<R_Role_Menu> _r_Role_MenuRepository;
        private readonly ICurrentUserContext _currentUserContext;
        private readonly IRecycleRepository _recycleRepository;

        public MenuController(IMenuRepository menuRepository, IBaseRepository<Config> configRepository, IBaseRepository<R_Role_Menu> r_Role_MenuRepository, ICurrentUserContext currentUserContext, IRecycleRepository recycleRepository)
        {
            _menuRepository = menuRepository;
            _configRepository = configRepository;
            _r_Role_MenuRepository = r_Role_MenuRepository;
            _currentUserContext = currentUserContext;
            _recycleRepository = recycleRepository;
        }
        [HttpGet]
        public async Task<ApiResult> GetBtnCodeList()
        {
            return new ApiResult(await _configRepository.GetListAsync(d => d.Type == nameof(Button) && !d.IsDeleted == false));
        }

        [HttpDelete, Authority]
        public async Task<ApiResult> Deletes([FromBody] DeletesInput commonDeleteInput)
        {
            foreach (var item in commonDeleteInput.Ids)
            {
                await _menuRepository.UpdateAsync(d => new Menu { DeleteTime = DateTime.Now, IsDeleted = true }, d => d.Id == item&&!d.IsDeleted);
            }
            return new ApiResult();
        }

        [HttpDelete, Authority(Action = nameof(Button.Delete))]
        public virtual Task<ApiResult> SoftDelete([FromBody] DeletesInput deleteInput)
        {
            return _recycleRepository.SoftDeleteAsync(deleteInput, _menuRepository);
        }

        [HttpGet, Authority]
        public async Task<ApiResult> GetListPages(int page, string key = null)
        {
            return await _menuRepository.GetListPagesAsync(page, key);
        }
        /// <summary>
        /// 获取菜单按钮
        /// </summary>
        /// <param name="menuId"></param>
        /// <param name="roleId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> BtnCode(int menuId = 0, int roleId = 0)
        {
            return await _menuRepository.BtnCodeByMenuIdAsync(menuId, roleId);
        }
        /// <summary>
        /// 树形菜单
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> TreeByRole(int roleId)
        {
            return await _menuRepository.TreeRoleIdAsync(roleId);
        }
        /// <summary>
        /// 菜单按钮授权
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> SetBtnPermissions([FromBody] RoleMenuBtnInput input)
        {
            //根据角色和菜单查询内容
            var model = await _r_Role_MenuRepository.GetModelAsync(d => d.RoleId == input.RoleId && d.MenuId == input.MenuId && d.IsDeleted == false);
            if (model.Id <= 0)
            {
                throw new ArgumentException("您还没有授权当前菜单功能模块");
            }
            if (model.BtnCodeIds != null)
            {
                //判断授权还是取消
                var list = model.BtnCodeIds.ToList();
                if (input.Status)
                {
                    //不包含则添加。包含放任不管
                    if (!list.Contains(input.BtnCodeId))
                    {
                        list.Add(input.BtnCodeId);
                    }
                }
                else
                {
                    //授权 包含则移除
                    if (list.Contains(input.BtnCodeId))
                    {
                        list.Remove(input.BtnCodeId);
                    }
                }
                model.ChangeBtnCodeIds(list.ToArray());
            }
            else
            {
                string[] arry = new string[] { input.BtnCodeId };
                //增加               
                model.ChangeBtnCodeIds(arry);
            }
            var sign = await _r_Role_MenuRepository.UpdateAsync(model);
            return sign > 0 ? new ApiResult(sign) : new ApiResult("菜单按钮授权失败！");


        }
        /// <summary>
        /// 授权菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost, Authority(Action = nameof(Button.Auth))]
        public async Task<ApiResult> AddPermissions([FromBody] PermissionsInput input)
        {
            var model = await _r_Role_MenuRepository.GetModelAsync(d => d.RoleId == input.RoleId && d.MenuId == input.MenuId);
            if (model.Id > 0)
            {
                return new ApiResult("已经存在该菜单权限了", 400);
            }
            R_Role_Menu addModel = R_Role_Menu.Create(input.RoleId, input.MenuId);
            var sign = await _r_Role_MenuRepository.AddAsync(addModel);
            return new ApiResult(sign);
        }

        [HttpGet, Authority]
        public async Task<ApiResult> Detail(int id)
        {
            if (id == 0)
            {
                throw new ArgumentNullException(nameof(id));
            }
            var res = await _menuRepository.GetModelAsync(d => d.Id == id);
            return new ApiResult(data: res);
        }
        [HttpPost, Authority]
        public async Task<ApiResult> Add([FromBody] MenuInput menuInput)
        {
            return await _menuRepository.AddToUpdateAsync(menuInput);
        }

        [HttpPut, Authority]
        public async Task<ApiResult> Modify([FromBody] MenuModifyInput menuModifyInput)
        {
            return await _menuRepository.ModifyAsync(menuModifyInput);
        }

        [HttpGet]
        public async Task<ApiResult> GetAllParentMenu()
        {
            return await _menuRepository.GetAllParentMenuAsync();
        }
        /// <summary>
        /// 左侧树形菜单
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> LoadLeftMenuTrees()
        {

            var userId = _currentUserContext.Id;
            return await _menuRepository.LoadLeftMenuTreesAsync(userId);
        }
    }
}
